package com.innovation.ic.b1b.monitor.base.service.masterSlave.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.innovation.ic.b1b.monitor.base.handler.ZookeeperAvailableJobHandler;
import com.innovation.ic.b1b.monitor.base.mapper.ZookeeperAvailableJobMapper;
import com.innovation.ic.b1b.monitor.base.model.Zookeeper;
import com.innovation.ic.b1b.monitor.base.model.ZookeeperAvailableJob;
import com.innovation.ic.b1b.monitor.base.pojo.constant.*;
import com.innovation.ic.b1b.monitor.base.pojo.enums.EnableEnum;
import com.innovation.ic.b1b.monitor.base.pojo.variable.ServiceResult;
import com.innovation.ic.b1b.monitor.base.pojo.variable.zookeeperAvailableJob.ZookeeperAvailableJobInfoRespPojo;
import com.innovation.ic.b1b.monitor.base.pojo.variable.zookeeperAvailableJob.ZookeeperAvailableJobListRespData;
import com.innovation.ic.b1b.monitor.base.service.masterSlave.ServiceHelper;
import com.innovation.ic.b1b.monitor.base.service.masterSlave.ZookeeperAvailableJobService;
import com.innovation.ic.b1b.monitor.base.vo.zookeeperAvailableJob.ZookeeperAvailableJobAddVo;
import com.innovation.ic.b1b.monitor.base.vo.zookeeperAvailableJob.ZookeeperAvailableJobListQueryVo;
import com.innovation.ic.b1b.monitor.base.vo.zookeeperAvailableJob.ZookeeperAvailableJobUpdateVo;
import lombok.extern.slf4j.Slf4j;
import org.quartz.JobDataMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.Date;
import java.util.List;

/**
 * @desc   ZookeeperAvailableJob表Service实现类
 * @author linuo
 * @time   2023年5月11日10:16:15
 */
@Slf4j
@Service
public class ZookeeperAvailableJobServiceImpl extends ServiceImpl<ZookeeperAvailableJobMapper, ZookeeperAvailableJob> implements ZookeeperAvailableJobService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());
    
    @Resource
    private ServiceHelper serviceHelper;

    /**
     * 添加zookeeper监控任务
     * @param zookeeperAvailableJobAddVo 添加zookeeper监控任务的Vo类
     * @return 返回添加结果
     */
    @Override
    public ServiceResult<Boolean> add(ZookeeperAvailableJobAddVo zookeeperAvailableJobAddVo) {
        boolean result = Boolean.FALSE;
        String message;

        Boolean aBoolean = judgeIfHaveSameData(null, zookeeperAvailableJobAddVo.getZookeeperId());
        if(aBoolean){
            message = "当前zookeeper监控任务已存在，请勿重复添加";
        }else{
            // 校验zookeeperId是否存在
            Zookeeper zookeeper = serviceHelper.getZookeeperMapper().selectById(zookeeperAvailableJobAddVo.getZookeeperId());
            if(zookeeper != null){
                ZookeeperAvailableJob zookeeperAvailableJob = new ZookeeperAvailableJob();
                BeanUtils.copyProperties(zookeeperAvailableJobAddVo, zookeeperAvailableJob);
                if(zookeeperAvailableJob.getEnable() == null){
                    zookeeperAvailableJob.setEnable(EnableEnum.NO.getCode());
                }
                zookeeperAvailableJob.setCreateTime(new Date(System.currentTimeMillis()));
                int insert = serviceHelper.getZookeeperAvailableJobMapper().insert(zookeeperAvailableJob);
                if(insert > 0){
                    message = ServiceResult.INSERT_SUCCESS;
                    result = Boolean.TRUE;

                    String jobId = TableNameConstant.ZOOKEEPER_AVAILABLE_JOB + "_" + zookeeperAvailableJob.getId();

                    // 组装任务参数
                    JobDataMap jobDataMap = new JobDataMap();
                    jobDataMap.put(JobDataMapConstant.ID, zookeeperAvailableJob.getId());

                    serviceHelper.getQuartzManager().createScheduleJob(jobId, ZookeeperAvailableJobHandler.class.getName(), "ZookeeperAvailableJobHandler", jobDataMap, zookeeperAvailableJob.getScheduleExpression());
                }else{
                    message = ServiceResult.INSERT_FAIL;
                }
            }else{
                message = "zookeeper信息不存在，请配置zookeeper信息后重新添加zookeeper监控任务";
            }
        }

        ServiceResult<Boolean> serviceResult = new ServiceResult<>();
        serviceResult.setSuccess(Boolean.TRUE);
        serviceResult.setResult(result);
        serviceResult.setMessage(message);
        return serviceResult;
    }

    /**
     * 查询zookeeper监控任务列表
     * @param zookeeperAvailableJobListQueryVo 查询zookeeper监控任务列表的Vo类
     * @param isMain 是否查询主库
     * @return 返回查询结果
     */
    @Override
    public ServiceResult<PageInfo<ZookeeperAvailableJobListRespData>> queryList(ZookeeperAvailableJobListQueryVo zookeeperAvailableJobListQueryVo, Boolean isMain) {
        PageHelper.startPage(zookeeperAvailableJobListQueryVo.getPageNo(), zookeeperAvailableJobListQueryVo.getPageSize());

        // 查询zookeeper可用任务列表数据
        List<ZookeeperAvailableJobListRespData> data = serviceHelper.getZookeeperAvailableJobMapper().queryList(zookeeperAvailableJobListQueryVo);
        PageInfo<ZookeeperAvailableJobListRespData> pageInfo = new PageInfo<>(data);

        return ServiceResult.ok(pageInfo, ServiceResult.SELECT_SUCCESS);
    }

    /**
     * 删除zookeeper监控任务
     * @param id 主键id
     * @return 返回删除结果
     */
    @Override
    public ServiceResult<Boolean> delete(Integer id) {
        boolean result = Boolean.FALSE;
        String message = ServiceResult.DELETE_FAIL;

        int i = serviceHelper.getZookeeperAvailableJobMapper().deleteById(id);
        if(i > 0){
            logger.info("已删除id为[{}]zookeeper监控任务", id);
            result = Boolean.TRUE;
            message = ServiceResult.DELETE_SUCCESS;

            try {
                // 删除任务
                String jobId = TableNameConstant.ZOOKEEPER_AVAILABLE_JOB + "_" + id;
                serviceHelper.getQuartzManager().deleteScheduleJob(jobId);
            }catch (Exception e){
                logger.info("删除zookeeper监控后台任务失败,原因:", e);
            }
        }else{
            logger.info("删除id为[{}]zookeeper监控任务失败，数据不存在", id);
        }

        return ServiceResult.ok(result, message);
    }

    /**
     * 获取zookeeper监控任务详情
     * @param id 主键id
     * @param isMain 是否查询主库
     * @return 返回查询结果
     */
    @Override
    public ServiceResult<ZookeeperAvailableJobInfoRespPojo> info(Integer id, Boolean isMain) {
        ZookeeperAvailableJobInfoRespPojo result = serviceHelper.getZookeeperAvailableJobMapper().info(id);
        return ServiceResult.ok(result, ServiceResult.SELECT_SUCCESS);
    }

    /**
     * 更新zookeeper监控任务
     * @param zookeeperAvailableJobUpdateVo 更新zookeeper监控任务的Vo类
     * @return 返回更新结果
     */
    @Override
    public ServiceResult<Boolean> update(ZookeeperAvailableJobUpdateVo zookeeperAvailableJobUpdateVo) {
        Boolean aBoolean = judgeIfHaveSameData(zookeeperAvailableJobUpdateVo.getId(), zookeeperAvailableJobUpdateVo.getZookeeperId());
        if(aBoolean){
            ServiceResult<Boolean> serviceResult = new ServiceResult<>();
            serviceResult.setSuccess(Boolean.TRUE);
            serviceResult.setResult(Boolean.FALSE);
            serviceResult.setMessage("当前zookeeper监控任务已存在，请勿重复添加");
            return serviceResult;
        }else{
            // 校验zookeeperId是否存在
            Zookeeper zookeeper = serviceHelper.getZookeeperMapper().selectById(zookeeperAvailableJobUpdateVo.getZookeeperId());
            if(zookeeper != null){
                ZookeeperAvailableJob historyData = serviceHelper.getZookeeperAvailableJobMapper().selectById(zookeeperAvailableJobUpdateVo.getId());

                int i = serviceHelper.getZookeeperAvailableJobMapper().updateInfo(zookeeperAvailableJobUpdateVo);
                if(i > 0){
                    logger.info("更新id为[{}]zookeeper监控任务成功", zookeeperAvailableJobUpdateVo.getId());

                    Integer enable = zookeeperAvailableJobUpdateVo.getEnable();
                    // 原来是启用现在关闭时需要暂停后台任务
                    if(historyData.getEnable().intValue() == EnableEnum.YES.getCode().intValue() && enable.intValue() == EnableEnum.NO.getCode().intValue()){
                        String jobId = TableNameConstant.ZOOKEEPER_AVAILABLE_JOB + "_" + zookeeperAvailableJobUpdateVo.getId();
                        logger.info("暂停后台任务,jobId:[{}]", jobId);
                        serviceHelper.getQuartzManager().pauseScheduleJob(jobId);
                    }else if(historyData.getEnable().intValue() == EnableEnum.NO.getCode().intValue() && enable.intValue() == EnableEnum.YES.getCode().intValue()) {
                        // 原来是关闭现在启用任务时需要恢复后台任务
                        String jobId = TableNameConstant.ZOOKEEPER_AVAILABLE_JOB + "_" + zookeeperAvailableJobUpdateVo.getId();
                        logger.info("恢复后台任务,jobId:[{}]", jobId);
                        serviceHelper.getQuartzManager().resumeScheduleJob(jobId);
                    }else{
                        String scheduleExpression = zookeeperAvailableJobUpdateVo.getScheduleExpression();
                        if(zookeeperAvailableJobUpdateVo.getEnable().intValue() == EnableEnum.YES.getCode().intValue() && !historyData.getScheduleExpression().equals(scheduleExpression)){
                            String jobId = TableNameConstant.ZOOKEEPER_AVAILABLE_JOB + "_" + zookeeperAvailableJobUpdateVo.getId();
                            serviceHelper.getQuartzManager().updateScheduleJob(jobId, scheduleExpression);
                        }
                    }

                    return ServiceResult.ok(Boolean.TRUE, ServiceResult.UPDATE_SUCCESS);
                }else{
                    logger.info("更新id为[{}]zookeeper监控任务失败", zookeeperAvailableJobUpdateVo.getId());
                    return ServiceResult.ok(Boolean.FALSE, ServiceResult.UPDATE_FAIL);
                }
            }else{
                logger.info("zookeeperId=[{}]的信息不存在", zookeeperAvailableJobUpdateVo.getZookeeperId());
                return ServiceResult.error(ServiceResult.UPDATE_FAIL);
            }
        }
    }

    /**
     * 执行任务
     * @param id 主键id
     * @return 返回执行结果
     */
    @Override
    public ServiceResult<Boolean> executeJob(Integer id) {
        ServiceResult<Boolean> serviceResult = new ServiceResult<>();

        try {
            String jobId = TableNameConstant.ZOOKEEPER_AVAILABLE_JOB + "_" + id;
            serviceHelper.getQuartzManager().runOnce(jobId);
        }catch (Exception e){
            serviceResult.setMessage(ServiceResult.OPERATE_FAIL);
            serviceResult.setResult(Boolean.FALSE);
            serviceResult.setSuccess(Boolean.FALSE);
            return serviceResult;
        }

        serviceResult.setMessage(ServiceResult.OPERATE_SUCCESS);
        serviceResult.setResult(Boolean.TRUE);
        serviceResult.setSuccess(Boolean.TRUE);
        return serviceResult;
    }

    /**
     * 判断是否有相同数据
     * @param id 主键id
     * @param zookeeperId zookeeperId
     * @return 返回判断结果
     */
    private Boolean judgeIfHaveSameData(Integer id, Integer zookeeperId){
        Boolean result = Boolean.FALSE;

        QueryWrapper<ZookeeperAvailableJob> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(ZookeeperAvailableJobConstant.ZOOKEEPER_ID, zookeeperId);
        if(id != null){
            queryWrapper.ne(ZookeeperAvailableJobConstant.ID, id);
        }
        Integer selectCount = serviceHelper.getZookeeperAvailableJobMapper().selectCount(queryWrapper);
        if(selectCount > 0){
            result = Boolean.TRUE;
        }

        return result;
    }
}